﻿#region Copyright Notice
// 
// 
// Copyright (c) 2009-2010 Anindya Chatterjee
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// 
// 
// 
#endregion
using System;
using System.Diagnostics;
using System.Serialization.Xml;
using System.Threading;
using System.Windows.Forms;
using ComponentFactory.Krypton.Toolkit;
using DesktopNotifier.Properties;
using DesktopNotifier.Settings;
using DesktopNotifier.Utility;
using Event.Plugin.Configuration;
using Timer=System.Windows.Forms.Timer;

namespace DesktopNotifier
{
    public sealed class NotificationIcon
    {
        private static AppConfig _config;
        private readonly ContextMenuStrip _notificationMenu;
        private readonly NotifyIcon _notifyIcon;
        private readonly Timer _timer;

        #region Initialize icon and menu

        public NotificationIcon()
        {
            _config = XObjectSerializer<AppConfig>.ReadFile(Constants.Settings, true);

            _notifyIcon = new NotifyIcon();
            _notificationMenu = new ContextMenuStrip();
            _notificationMenu.Items.AddRange(InitializeMenu());

            _notifyIcon.DoubleClick += IconDoubleClick;
            _notifyIcon.Click += IconClick;
            _notifyIcon.ContextMenuStrip = _notificationMenu;
            _notifyIcon.Icon = Resources.DesktopAlert;

            _timer = new Timer {Interval = 1000};
            _timer.Tick += TimerTick;
            _timer.Enabled = true;
        }

        private static ToolStripItem[] InitializeMenu()
        {
            var menu = new ToolStripItem[]
                           {
                               new ToolStripMenuItem("Settings", null, MenuSettingsClick),
                               new ToolStripSeparator(),
                               new ToolStripMenuItem("Help", null, MenuHelpClick),
                               new ToolStripMenuItem("Check Update", null, MenuUpdateClick),
                               new ToolStripMenuItem("Feedback", null, MenuFeedbackClick),
                               new ToolStripMenuItem("Post A Bug", null, MenuPostBug),
                               new ToolStripMenuItem("Donate", null, MenuDonateClick),
                               new ToolStripMenuItem("About", null, MenuAboutClick),
                               new ToolStripSeparator(),
                               new ToolStripMenuItem("Exit", null, MenuExitClick),
                           };
            // skinning
            new KryptonManager
                {
                    GlobalApplyToolstrips = true,
                    GlobalAllowFormChrome = true,
                    GlobalPaletteMode = _config.Theme
                };

            return menu;
        }

        #endregion

        #region Main - Program entry point

        /// <summary>Program entry point.</summary>
        /// <param name="args">Command Line Arguments</param>
        [STAThread]
        public static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            try
            {
                bool isFirstInstance;
                // Please use a unique name for the mutex to prevent conflicts with other programs
                using (new Mutex(true, "DesktopNotifier", out isFirstInstance))
                {
                    if (isFirstInstance)
                    {
                        var notificationIcon = new NotificationIcon();
                        notificationIcon._notifyIcon.Visible = true;

                        // handling safe mode scenario
                        if (_config.SafeMode)
                        {
                            new SafeModeForm().ShowDialog();
                        }

                        // initialize event handling
                        new EventManager(_config);

                        // check for update
                        if (_config.AutomaticUpdate)
                            MenuUpdateClick(null, null);

                        // prompt for donation and feedback
                        if (_config.FirstRun != DateTime.MinValue
                            && DateTime.Now.Subtract(_config.FirstRun).TotalDays > 90
                            && (!_config.FeedBackGiven || !_config.DonationGiven))
                        {
                            new FeedBack(_config).ShowDialog();
                        }

                        // start application
                        Application.Run();
                        notificationIcon._notifyIcon.Dispose();
                    }
                    else
                    {
                        MessageBox.Show("Already one instanse is running.");
                    }
                }
            }
            catch (Exception ex)
            {
                new BugReport(null, _config) {Bug = ex, StartPosition = FormStartPosition.CenterScreen}.ShowDialog();
                if (_config != null)
                {
                    _config.SafeMode = true;
                    XObjectSerializer<AppConfig>.WriteFile(Constants.Settings, _config, true);
                }
                DialogResult result = MessageBox.Show("Would you like to restart Ozone?", "Confirmation",
                                                      MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                    Application.Restart();
                else
                    Application.Exit();
            }
        }

        #endregion

        #region Event Handlers

        private static void MenuAboutClick(object sender, EventArgs e)
        {
            new About().ShowDialog();
        }

        private static void MenuExitClick(object sender, EventArgs e)
        {
            try
            {
                XObjectSerializer<AppConfig>.WriteFile(Constants.Settings, _config, true);
                Application.Exit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error in Ozone");
            }
        }

        private static void MenuUpdateClick(object sender, EventArgs e)
        {
            try
            {
                var updateUtil = new UpdateUtil(_config);
                updateUtil.CheckUpdate(sender);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error in Ozone");
            }
        }

        private static void MenuFeedbackClick(object sender, EventArgs e)
        {
            try
            {
                Process.Start(Constants.FeedBackUrl);
                if (_config != null)
                    _config.FeedBackGiven = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error in Ozone");
            }
        }

        private static void MenuPostBug(object sender, EventArgs e)
        {
            try
            {
                Process.Start(Constants.BugReportUrl);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error in Ozone");
            }
        }

        private static void MenuDonateClick(object sender, EventArgs e)
        {
            try
            {
                Process.Start(Constants.DonateUrl);
                if (_config != null)
                    _config.DonationGiven = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error in Ozone");
            }
        }

        private static void IconDoubleClick(object sender, EventArgs e)
        {
            new ConfigForm(_config).ShowDialog();
        }

        private static void IconClick(object sender, EventArgs e)
        {
            NotifyUtility.IsAnimating = false;
        }

        private static void MenuSettingsClick(object sender, EventArgs e)
        {
            new ConfigForm(_config).ShowDialog();
        }

        private static void MenuHelpClick(object sender, EventArgs e)
        {
            try
            {
                Process.Start(Constants.HelpFile);
            }
            catch (Exception msg)
            {
                MessageBox.Show(msg.Message, "Error in Ozone");
            }
        }

        private void TimerTick(object sender, EventArgs e)
        {
            _notifyIcon.Icon = NotifyUtility.IsAnimating ? NotifyUtility.GetAnimatedIcon() : Resources.DesktopAlert;
            if (NotifyUtility.ShowBalloonTip)
            {
                _notifyIcon.ShowBalloonTip(100, "Ozone",
                                           "An event is captured.",
                                           ToolTipIcon.Info);
                NotifyUtility.ShowBalloonTip = false;
            }
        }

        #endregion
    }
}